namespace Cik.Gapi4Net.Core.AcsynRequest
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using System.Net;

    internal class Downloader : IDownloader
    {
        private readonly IList<string> _urls;

        public Downloader()
        {
            _urls = new List<string>();
        }

        public void Add(string url)
        {
            Contract.Assert(!string.IsNullOrEmpty(url), "Url is null or empty");

            _urls.Add(url);
        }

        public IEnumerable<IAsync> DownloadAll(Action<Async<string>> action)
        {
            return _urls.Select(url => Async.Parallel(
                ProcessResultFromDownloadContentFromUrl(url, action)
                                           ));
        }

        private IEnumerable<IAsync> ProcessResultFromDownloadContentFromUrl(string url, Action<Async<string>> action)
        {
            var req = WebRequest.Create(url);

            // asynchronously get the response from http server
            var response = req.GetResponseAsync();
            yield return response;

            var resp = response.Result.GetResponseStream();

            // download HTML using the asynchronous extension method
            // instead of using synchronous StreamReader
            var html = resp.ReadToEndAsync().ExecuteAsync<string>();

            yield return html;

            action(html);
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

        public int Count
        {
            get { return _urls.Count; }
        }
    }
}